import { defineStore, acceptHMRUpdate } from 'pinia'

/**
 * 页签对象
 */
export interface TagView {
  /** 页签名称 */
  name: string
  /** 页签标题 */
  title: string
  /** 页签路由路径 */
  path: string
  /** 页签路由完整路径 */
  fullPath: string
  /** 页签图标 */
  icon?: string
  /** 是否固定页签 */
  affix?: boolean
  /** 是否开启缓存 */
  keepAlive?: boolean
  /** 路由查询参数 */
  query?: any
}

export const useTagsViewStore = defineStore('tagsView', () => {
  const visitedViews = ref<TagView[]>([])
  const cachedViews = ref<string[]>([])
  const router = useRouter()
  const route = useRoute()

  /**
   * 添加标签视图
   */
  function addVisitedView(view: TagView) {
    // 如果已经存在于已访问的视图列表中，则不再添加
    if (visitedViews.value.some(v => v.path === view.path)) {
      return
    }
    // 如果视图是固定的（affix），则在已访问的视图列表的开头添加
    if (view.affix) {
      visitedViews.value.unshift(view)
    } else {
      // 如果视图不是固定的，则在已访问的视图列表的末尾添加
      visitedViews.value.push(view)
    }
  }

  /**
   * 添加缓存
   */
  function addCachedView(view: TagView) {
    const viewName = view.name
    // 如果缓存视图名称已经存在于缓存视图列表中，则不再添加
    if (cachedViews.value.includes(viewName)) {
      return
    }

    // 如果视图需要缓存（keepAlive），则将其路由名称添加到缓存视图列表中
    if (view.keepAlive) {
      cachedViews.value.push(viewName)
    }
  }

  /**
   * 删除标签视图
   */
  function delVisitedView(view: TagView) {
    return new Promise(resolve => {
      for (const [i, v] of visitedViews.value.entries()) {
        // 找到与指定视图路径匹配的视图，在已访问视图列表中删除该视图
        if (v.path === view.path) {
          visitedViews.value.splice(i, 1)
          break
        }
      }
      resolve([...visitedViews.value])
    })
  }

  /**
   * 删除缓存
   */
  function delCachedView(view: TagView) {
    const viewName = view.name
    return new Promise(resolve => {
      const index = cachedViews.value.indexOf(viewName)
      if (index > -1) {
        cachedViews.value.splice(index, 1)
      }
      resolve([...cachedViews.value])
    })
  }

  function delOtherVisitedViews(view: TagView) {
    return new Promise(resolve => {
      visitedViews.value = visitedViews.value.filter(v => {
        return v?.affix || v.path === view.path
      })
      resolve([...visitedViews.value])
    })
  }

  /**
   * 删除其他缓存
   */
  function delOtherCachedViews(view: TagView) {
    const viewName = view.name as string
    return new Promise(resolve => {
      const index = cachedViews.value.indexOf(viewName)
      if (index > -1) {
        cachedViews.value = cachedViews.value.slice(index, index + 1)
      } else {
        cachedViews.value = []
      }
      resolve([...cachedViews.value])
    })
  }

  /**
   * 刷新标签
   */
  function updateVisitedView(view: TagView) {
    for (let v of visitedViews.value) {
      if (v.path === view.path) {
        v = Object.assign(v, view)
        break
      }
    }
  }

  /**
   * 添加标签
   */
  function addView(view: TagView) {
    addVisitedView(view)
    addCachedView(view)
  }

  /**
   * 删除标签
   */
  function delView(view: TagView) {
    return new Promise(resolve => {
      delVisitedView(view)
      delCachedView(view)
      resolve({
        visitedViews: [...visitedViews.value],
        cachedViews: [...cachedViews.value]
      })
    })
  }

  /**
   * 删除除自身以外其他标签
   */
  function delOtherViews(view: TagView) {
    return new Promise(resolve => {
      delOtherVisitedViews(view)
      delOtherCachedViews(view)
      resolve({
        visitedViews: [...visitedViews.value],
        cachedViews: [...cachedViews.value]
      })
    })
  }

  /**
   * 删除左边标签
   */
  function delLeftViews(view: TagView) {
    return new Promise<{ visitedViews: TagView[] }>(resolve => {
      const currIndex = visitedViews.value.findIndex(v => v.path === view.path)
      if (currIndex === -1) {
        return
      }
      visitedViews.value = visitedViews.value.filter((item, index) => {
        // 大于当前索引（右边）的标签或者固定标签视图不删除
        if (index >= currIndex || item?.affix) {
          return true
        }
        delCachedView(item)
        return false
      })
      resolve({
        visitedViews: [...visitedViews.value]
      })
    })
  }

  /**
   * 删除右边标签
   */
  function delRightViews(view: TagView) {
    return new Promise<{ visitedViews: TagView[] }>(resolve => {
      const currIndex = visitedViews.value.findIndex(v => v.path === view.path)
      if (currIndex === -1) {
        return
      }
      visitedViews.value = visitedViews.value.filter((item, index) => {
        // 小于当前索引（左边）的标签或者固定标签视图不删除
        if (index <= currIndex || item?.affix) {
          return true
        }
        delCachedView(item)
        return false
      })
      resolve({
        visitedViews: [...visitedViews.value]
      })
    })
  }

  /**
   * 删除所有标签
   */
  function delAllViews() {
    return new Promise(resolve => {
      const affixTags = visitedViews.value.filter(tag => tag?.affix)
      visitedViews.value = affixTags
      cachedViews.value = []
      resolve({
        visitedViews: [...visitedViews.value],
        cachedViews: [...cachedViews.value]
      })
    })
  }

  /**
   * 删除所有标签视图
   */
  function delAllVisitedViews() {
    return new Promise(resolve => {
      const affixTags = visitedViews.value.filter(tag => tag?.affix)
      visitedViews.value = affixTags
      resolve([...visitedViews.value])
    })
  }

  /**
   * 删除所有标签缓存
   */
  function delAllCachedViews() {
    return new Promise(resolve => {
      cachedViews.value = []
      resolve([...cachedViews.value])
    })
  }

  /**
   * 关闭当前tagView
   */
  function closeCurrentView() {
    const tag: TagView = {
      name: route.name as string,
      title: route.meta.title as string,
      path: route.path,
      fullPath: route.fullPath,
      affix: route.meta?.affix,
      keepAlive: route.meta?.keepAlive,
      query: route.query
    }
    delView(tag).then((res: any) => {
      if (isActive(tag)) {
        toLastView(res.visitedViews, tag)
      }
    })
  }

  function isActive(tag: TagView) {
    return tag.path === route.path
  }

  function toLastView(visitedViews: TagView[], view?: TagView) {
    const latestView = visitedViews.slice(-1)[0]
    if (latestView && latestView.fullPath) {
      router.push(latestView.fullPath)
    } else {
      // if (view?.name === 'Home') {
      //   router.replace('/redirect' + view.fullPath)
      // } else {
      //   router.push('/')
      // }
      router.replace('/redirect' + view.fullPath)
    }
  }

  return {
    visitedViews,
    cachedViews,
    addVisitedView,
    addCachedView,
    delVisitedView,
    delCachedView,
    delOtherVisitedViews,
    delOtherCachedViews,
    updateVisitedView,
    addView,
    delView,
    delOtherViews,
    delLeftViews,
    delRightViews,
    delAllViews,
    delAllVisitedViews,
    delAllCachedViews,
    closeCurrentView,
    isActive,
    toLastView
  }
})

if (import.meta.hot) {
  import.meta.hot.accept(acceptHMRUpdate(useTagsViewStore, import.meta.hot))
}
